如何编写Linux 驱动程序 |
您所在的位置:网站首页 › insmod invalid module format › 如何编写Linux 驱动程序 |
以装载和卸载模块为例: 1、首先输入代码 #include linux/init.h #include linux/module.h 2、然后输入下方的代码: static int my_init(void) { return 0 } static void my_exit(void) 3、然后在输入下方的代码: { return } module_init(my_init) module_exit(my_exit)这样就完成了。 linux 编译安装驱动有两种,动态加载与静态加载动态加载 一,编译,在指点内核树下编译,生成.o文件或.ko文件 二,将生成的.o或.ko文件拷到相应目录,一般是/lib/module/kernel下面 三,用insmod命令加载,用rmmod命令卸载 静态加载 静态加载主要就是编译内核。就是将编写好的驱动放进内核相应的目录下面。然后编译内核。然后运行编译好的内核。 linux下编译运行驱动嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发。 按照如下方法就可以成功编译出hello world模块驱动。 1、首先确定本机linux版本 怎么查看Linux的内核kernel版本? 'uname'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用'uname'参数可以查看当前服务器内核运行的各个状态。 #uname -a Linux whh 3.5.0-19-generic #30-Ubuntu SMPTue Nov 13 17:49:53 UTC 2012 i686 i686 i686 GNU/Linux
只打印内核版本,以及主要和次要版本: #uname -r 3.5.0-19-generic
要打印系统的体系架构类型,即的机器是32位还是64位,使用: #uname -p i686
/proc/version 文件也包含系统内核信息: # cat /proc/version Linux version 3.5.0-19-generic(buildd@aatxe) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) ) #30-UbuntuSMP Tue Nov 13 17:49:53 UTC 2012
发现自己的机器linux版本是:3.5.0-19-generic 2、下载机器内核对应linux源码 到下面网站可以下载各个版本linux源码https://www.kernel.org/ 如我的机器3.5.0版本源码下载地址为:https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.tar.bz2 下载完后,找一个路径解压,如我解压到/linux-3.5/ 然后很重要的一步是:执行命令uname -r,可以看到Ubuntu的版本信息是3.5.0-19-generic 。进入linux源码目录,编辑Makefile,将EXTRAVERSION = 修改为EXTRAVERSION= -19-generic。 这些都是要配置源码的版本号与系统版本号,如果源码版本号和系统版本号不一致,在加载模块的时候会出现如下错误:insmod: error inserting 'hello.ko': -1 Invalid module format。 原因很明确:编译时用的hello.ko的kenerl 不是我的pc的kenerl版本。
执行命令cp /boot/config-3.5.0-19-generic ./config,覆盖原有配置文件。 进入linux源码目录,执行make menuconfig配置内核,执行make编译内核。 3、写一个最简单的linux驱动代码hello.c
/*====================================================================== Asimple kernel module: "hello world" ======================================================================*/ #include linux/init.h #include linux/module.h MODULE_LICENSE("zeroboundaryBSD/GPL") static int hello_init(void) { printk(KERN_INFO"Hello World enter\n") return0 }
static void hello_exit(void) { printk(KERN_INFO"Hello World exit\n ") }
module_init(hello_init) module_exit(hello_exit)
MODULE_AUTHOR("zeroboundary") MODULE_DESCRIPTION("A simple HelloWorld Module") MODULE_ALIAS("a simplestmodule")
4、写一个Makefile对源码进行编译 KERN_DIR = /linux-3.5 all: make-C $(KERN_DIR) M=`pwd` modules clean: make-C $(KERN_DIR) M=`pwd` clean
obj-m += hello.o
5、模块加载卸载测试 insmod hello.ko rmmod hello.ko
然后dmesg|tail就可以看见结果了 最后,再次编译驱动程序hello.c得到hello.ko。执行insmod ./hello.ko,即可正确insert模块。
使用insmod hello.ko 将该Module加入内核中。在这里需要注意的是要用 su 命令切换到root用户,否则会显示如下的错误:insmod: error inserting 'hello.ko': -1 Operation not permitted
内核模块版本信息的命令为modinfo hello.ko 通过lsmod命令可以查看驱动是否成功加载到内核中 通过insmod命令加载刚编译成功的time.ko模块后,似乎系统没有反应,也没看到打印信息。而事实上,内核模块的打印信息一般不会打印在终端上。驱动的打印都在内核日志中,我们可以使用dmesg命令查看内核日志信息。dmesg|tail 可能还会遇到这种问题insmod: error inserting 'hello.ko': -1 Invalid module format 用dmesg|tail查看内核日志详细错误 disagrees about version of symbolmodule_layout,详细看这里。 http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/index.html 在X86上我的办法是: make -C/usr/src/linux-headers-3.5.0-19-generic SUBDIRS=$PWD modules 欢迎分享,转载请注明来源:内存溢出 原文地址:https://www.outofmemory.cn/yw/6158268.html |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |